<template>
<q-dialog v-model="isUploadDialog" persistent>
    <q-card>
        <q-card-section class="row items-center q-pa-sm">
            <div class="column">

                <q-uploader flat draggable :auto-upload="false"  label="上传视频" multiple class="bolder-line" accept=".mp4" @added="handleAddFiles" @rejected="handleRejectFiles" @removed="handleRemoveFiles"> <template v-slot:header="scope">
                        <div class="row no-wrap justify-between">
                            <div class="q-pa-sm">
                                <div>上传文件</div>
                                <div class="text-caption">文件类型：.mp4</div>
                            </div>
                            <q-btn v-if="scope.canAddFiles" type="a" icon="add_box" round dense flat>
                                <q-uploader-add-trigger />

                            </q-btn>
                            <q-btn v-if="scope.canUpload" icon="cloud_upload" @click="scope.upload" round dense flat >
                                <q-tooltip>Upload Files</q-tooltip>
                              </q-btn>
                        </div>

                    </template>
                    <template v-slot:list="scope">

                        <q-list v-if="fileList.length==0">
                            <q-item class="row items-center text-caption">
                                <q-item-label class="full-width column items-center q-gutter-sm ellipsis">
                                    <span>将文件拖到此处</span> <span class="text-italic text-primary">或点击选择
                                        <q-uploader-add-trigger /></span>
                                </q-item-label>
                                <div class="row items-center text-caption"> </div>
                            </q-item>

                        </q-list>

                        <q-list separator>

                            <q-item v-for="file in scope.files" :key="file.__key">
                                <q-item-section>
                                    <q-item-label class="full-width ellipsis">
                                        {{ file.name }}
                                    </q-item-label>
                                    <q-item-label caption>
                                        {{ file.__sizeLabel }}
                                    </q-item-label>
                                </q-item-section>

                                <q-item-section v-if="file.__img" thumbnail class="gt-xs">
                                    <img :src="file.__img.src">
                                </q-item-section>

                                <q-item-section side>
                                    <q-btn class="gt-xs" size="12px" flat dense round icon="delete" @click="scope.removeFile(file)" />
                                </q-item-section>
                            </q-item>

                        </q-list>

                    </template>
                </q-uploader>

                <!-- <el-upload ref="upload" class="upload-demo" drag :multiple="true" :action="uploadurl" accept=".mov,.mp4" :auto-upload="false" :on-change="handleChange" :headers="uploadheaders" :on-remove="handleremovefile">
                    <i class="el-icon-upload"></i>
                    <div class="el-upload__text">
                        将文件拖到此处，或<em>点击上传</em>
                    </div>
                    <div class="el-upload__tip" slot="tip">
                        上传文件类型：mov、mp4视频文件
                    </div>
                </el-upload> -->
            </div>
        </q-card-section>

        <q-card-actions align="right">
            <q-btn outline label="上传" icon="upload" color="primary" @click="submitUpload" />
            <q-btn outline label="取消" color="primary" v-close-popup />
        </q-card-actions>
    </q-card>
</q-dialog>
</template>

<script>
import request from "assets/utils/request";
export default {
    // name: 'ComponentName',
    data() {
        return {
            fileList: [],
        }
    },
    methods: {
        async ParseFile(file) {
            let buffer = await fileParse(file, "buffer");
            return buffer;
        },
        testQueue() {
            let fileList = this.data;
            let fileNum = 0;
            fileList.forEach((v) => {
                if (v.status == 1) {
                    fileNum += 1;
                }
            });
            if (fileNum <= 2) {
                this.uploadTask();
            }
        },
        uploadTask() {
            let fileNum = 0;
            let fileList = this.data;
            console.log("文件列表", fileList);
            let taskNum = 0;
            fileList.forEach((v) => {
                if (v.status < 2) {
                    taskNum += 1;
                }
            });
            this.taskNum = taskNum;
            for (let index = 0; index <= fileList.length - 1; index++) {
                let v = fileList[index];
                console.log("数据", v);
                if (v.status == 0 && fileNum < 1) {
                    console.log("开始上传");
                    v.statusMsg = "文件解析中……";
                    v.status = 1;
                    v.isupload = false;
                    v.isload = true;
                    v.fileList = fileList;
                    let file = v.file;
                    v.name = file.name;

                    this.ParseFile(file).then((buffer) => {
                        v.statusMsg = "切片中……";
                        let spark = new SparkMD5.ArrayBuffer(),
                            hash,
                            suffix;
                        spark.append(buffer);
                        hash = spark.end();
                        suffix = /\.([0-9a-zA-Z]+)$/i.exec(file.name)[1];
                        // 每个文件2Mb来切片
                        let chunksize = 2 * 1024 * 1024;
                        let total = Math.ceil(file.size / chunksize);
                        v.total = total;
                        let partList = [],
                            cur = 0;
                        for (let i = 0; i < v.total; i++) {
                            let item = {
                                chunk: file.slice(cur, cur + chunksize),
                                filename: `${hash}_${i}.${suffix}`,
                            };
                            cur += chunksize;
                            partList.push(item);
                        }
                        v.statusMsg = "解析完成";
                        v.partList = partList;
                        v.hash = hash;
                        this.verifymd5(v);
                    });

                    fileNum = fileNum + 1;
                    console.log("正在上传的文件数", fileNum);
                }
            }
        },
        uploadSuccess(v) {
            v.status = 2;
            v.statusMsg = "上传成功！";
            this.testQueue();
            let num = 0;
            let fileList = this.data;
            fileList.forEach((v) => {
                if (v.status == 2) {
                    num += 1;
                }
            });
            if (num == fileList.length) {
                this.handlesuccess();
            }
        },

        submitUpload() {
            if (this.fileList.length > 0) {
             
                    let fileList = this.fileList;
                    fileList.forEach((v, i) => {
                        this.data.push({
                            name: v.name,
                            process: 0,
                            status: 0,
                            fileSize: (v.size / 1024 / 1024).toFixed(2) + "MB",
                            statusMsg: "上传队列中……",
                            isUploaded: false,
                            file: v,
                            fileList: [],
                            uploadres: [],
                            partList: [],
                            hash: "",
                            rawfilename: "",
                            total: 0,
                            isupload: false,
                            curchunk: 0,
                            check: 0,
                            checkedPartlist: [],
                            leftPartlist: [],
                            pid: this.pid,
                        });
                        this.isUpload = false;
                    
                        this.fileList = [];
                    });
                    setTimeout(() => {
                        this.uploadTask();
                    }, 500);

                    // this.isload = true;
                    // this.verifymd5();
                
            } else {
                this.$message.error("请先选择要上传的文件！");
            }
        },

        async handleChange(file, fileList) {
            console.log(fileList);
            this.fileList = fileList;
            this.isupload = true;
        },
        //文件校验

        async verifymd5(v) {
            v.statusMsg = "检查缓存……";
            let data = {
                md5: v.hash,
            };
            //检查是否数据库存在相同文件
            searchMD5(data).then((res) => {
                let data = res.data.data;
                if (data.length > 0) {
                    this.uploadSuccess(v);
                    return;
                }
                //检查本地缓存是否有上传过的分片文件
                var checklist = [];
                v.partList.map((item, index) => {
                    let fn = () => {
                        let filedata = {
                            hash: v.hash,
                            filename: item.filename,
                        };

                        checkuploadfile(filedata).then((res) => {
                            let data = res.data;
                            if (data.code == 11) {
                                v.curchunk += 1;
                            }
                            //将没有上传的分片文件push到新的文件数组
                            v.check += 1;
                            if (data.code == 10) {
                                v.checkedPartlist.push(item);
                            }
                            v.process = parseFloat(
                                ((this.curchunk / this.total) * 100).toFixed(2)
                            );
                            if (v.check == v.total) {
                                v.statusMsg = "检查缓存完成";
                                this.sendRequest(v);
                            }
                        });
                    };
                    checklist.push(fn);
                });
                var i = 0;
                let send = async () => {
                    if (i >= checklist.length) {
                        return;
                    }
                    await checklist[i]();
                    i++;

                    send();
                };
                send();
            });
        },
        //发送文件上传请求
        async sendRequest(v) {
            // 根据100个切片创造100个请求（集合）
            //开始真正上传，将checklist里没有上传的分片文件上传
            v.isUploaded = true;
            //分片文件已经全部上传完毕
            if (v.curchunk == v.total) {
                let complete = async () => {
                    let data = {
                        hash: v.hash,
                        rawfilename: v.rawfilename,
                        pid: this.pid,
                    };
                    await mergeVideo(data);
                };

                complete().then((res) => {
                    console.log("长传这儿", res);
                    this.uploadSuccess(v);
                    return;
                });
            }
            //上传剩余分片文件
            let requestList = [];
            v.checkedPartlist.map((item, index) => {
                // 每一个函数都是发送一个切片的请求
                let fn = () => {
                    let formData = new FormData();
                    formData.append("chunk", item.chunk);
                    formData.append("hash", v.hash);
                    formData.append("filename", item.filename);
                    uploadvideo(formData).then((res) => {
                        res = res.data;
                        if (res.code == 1) {
                            v.curchunk += 1;
                            // 传完的切片我们把它移除掉
                            if (v.curchunk == v.total) {
                                complete().then((res) => {
                                    console.log("上传完毕这儿", res);
                                    this.uploadSuccess(v);
                                    return;
                                });
                            }
                        } else {
                            v.leftPartlist.push(item);
                        }
                        v.process = parseFloat(((v.curchunk / v.total) * 100).toFixed(2));
                    });
                };
                requestList.push(fn);
            });

            // 传递：并行(ajax.abort())/串行(基于标志控制不发送)
            var i = 0;
            let complete = async () => {
                let data = {
                    hash: v.hash,
                    rawfilename: v.name,
                    pid: this.pid,
                };
                await mergeVideo(data);
            };
            let send = async () => {
                // 已经中断则不再上传
                // if (this.abort) return;
                if (i >= requestList.length) {
                    return;
                }
                await requestList[i]();
                i++;
                send();
            };
            send();
        },
        handleRaw(files){
            console.log('raw',files);
        },
        handleAddFiles(files) {
            console.log('add files', files);

            this.fileList = this.fileList.concat(files);
            console.log('filelist', this.fileList);
        },
        handleRemoveFiles(file) {
            let index = this.fileList.findIndex(i => i.name == file.name);
            if (index != -1) {
                this.fileList.splice(index, 1)
            }

            console.log('remove files', file);
        },
        handleRejectFiles(files) {
            console.log('reject files', files);
        },

        handlesuccess() {
            this.$message.success("上传完了！");
            this.loadFolderList();
            this.loadfilelists();
        },
    }
}
</script>
